from functools import wraps
from typing import List, Callable
from fastapi import HTTPException, status

from app.models.user import User


def require_permission(permission: str):
    """权限装饰器 - 要求用户具有特定权限"""
    def decorator(func: Callable) -> Callable:
        @wraps(func)
        async def wrapper(*args, **kwargs):
            # 获取当前用户
            current_user = None
            for arg in args:
                if isinstance(arg, User):
                    current_user = arg
                    break
            
            if current_user is None:
                for key, value in kwargs.items():
                    if isinstance(value, User):
                        current_user = value
                        break
            
            if current_user is None:
                raise HTTPException(
                    status_code=status.HTTP_403_FORBIDDEN,
                    detail="无法获取用户信息"
                )
            
            # 检查权限
            if not current_user.has_permission(permission):
                raise HTTPException(
                    status_code=status.HTTP_403_FORBIDDEN,
                    detail=f"需要权限: {permission}"
                )
            
            return await func(*args, **kwargs)
        return wrapper
    return decorator


def require_role(role_name: str):
    """角色装饰器 - 要求用户具有特定角色"""
    def decorator(func: Callable) -> Callable:
        @wraps(func)
        async def wrapper(*args, **kwargs):
            # 获取当前用户
            current_user = None
            for arg in args:
                if isinstance(arg, User):
                    current_user = arg
                    break
            
            if current_user is None:
                for key, value in kwargs.items():
                    if isinstance(value, User):
                        current_user = value
                        break
            
            if current_user is None:
                raise HTTPException(
                    status_code=status.HTTP_403_FORBIDDEN,
                    detail="无法获取用户信息"
                )
            
            # 检查角色
            if not current_user.has_role(role_name):
                raise HTTPException(
                    status_code=status.HTTP_403_FORBIDDEN,
                    detail=f"需要角色: {role_name}"
                )
            
            return await func(*args, **kwargs)
        return wrapper
    return decorator


def require_any_permission(permissions: List[str]):
    """权限装饰器 - 要求用户具有任意一个权限"""
    def decorator(func: Callable) -> Callable:
        @wraps(func)
        async def wrapper(*args, **kwargs):
            current_user = None
            for arg in args:
                if isinstance(arg, User):
                    current_user = arg
                    break
            
            if current_user is None:
                for key, value in kwargs.items():
                    if isinstance(value, User):
                        current_user = value
                        break
            
            if current_user is None:
                raise HTTPException(
                    status_code=status.HTTP_403_FORBIDDEN,
                    detail="无法获取用户信息"
                )
            
            # 检查任意权限
            user_permissions = current_user.get_all_permissions()
            has_permission = any(perm in user_permissions for perm in permissions)
            
            if not has_permission:
                raise HTTPException(
                    status_code=status.HTTP_403_FORBIDDEN,
                    detail=f"需要以下权限之一: {', '.join(permissions)}"
                )
            
            return await func(*args, **kwargs)
        return wrapper
    return decorator


def require_all_permissions(permissions: List[str]):
    """权限装饰器 - 要求用户具有所有权限"""
    def decorator(func: Callable) -> Callable:
        @wraps(func)
        async def wrapper(*args, **kwargs):
            current_user = None
            for arg in args:
                if isinstance(arg, User):
                    current_user = arg
                    break
            
            if current_user is None:
                for key, value in kwargs.items():
                    if isinstance(value, User):
                        current_user = value
                        break
            
            if current_user is None:
                raise HTTPException(
                    status_code=status.HTTP_403_FORBIDDEN,
                    detail="无法获取用户信息"
                )
            
            # 检查所有权限
            user_permissions = current_user.get_all_permissions()
            has_all_permissions = all(perm in user_permissions for perm in permissions)
            
            if not has_all_permissions:
                raise HTTPException(
                    status_code=status.HTTP_403_FORBIDDEN,
                    detail=f"需要以下所有权限: {', '.join(permissions)}"
                )
            
            return await func(*args, **kwargs)
        return wrapper
    return decorator